// ****************************************************************************
// *     Filename:  g4test.cc
// *      Created:  2012-09-14 11:07:01
// *      Version:  1.0
// *     Revision:  0
// *       Author:  Tran Hoai Nam (nam), nam@kuno-g.phys.sci.osaka-u.ac.jp
// * Organization:  Osaka University
// *      License:  Geant4 Software License 
// *                http://geant4.cern.ch/license/LICENSE.html
// *  Description:  Main 
// ****************************************************************************


#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "G4PhysListFactory.hh"
#include "G4VModularPhysicsList.hh"
#include "Randomize.hh"

#include "PhysicsList.hh"
#include "PhysicsListMessenger.hh"
#include "DetectorConstruction.hh"
#include "PrimaryGeneratorAction.hh"
#include "EventAction.hh"
#include "HistoManager.hh"

#ifdef G4VIS_USE
#include "G4VisExecutive.hh"
#endif

#ifdef G4UI_USE
#include "G4UIExecutive.hh"
#endif
int main(int argc,char** argv)
{
	//Random engine
	long seeds[1];	//default Random engine: HepJamesRandom that needs only 1 seed
	time_t systime = time(NULL);
	seeds[0] = (long) systime;
	G4cout<<systime<<"\t"<<seeds[0]<<G4endl;
	CLHEP::HepRandom::setTheSeeds(seeds);
	CLHEP::HepRandom::showEngineStatus();

  // Construct the default run manager
  G4RunManager* runManager = new G4RunManager;
	// Save random seed in order to re-run later
	//runManager->SetRandomNumberStore(true);

  // set mandatory initialization classes
  //G4VUserDetectorConstruction* detector = new DetectorConstruction;
  DetectorConstruction* detector = new DetectorConstruction;
  runManager->SetUserInitialization(detector);
	
  //Physics list, using physics builder
  G4PhysListFactory physListFact;
  G4VModularPhysicsList* modulPhysList = 0;
  PhysicsListMessenger* physListMess = 0;
  G4String physName = "";

  // Physics List name defined via 2nd argument
  //if (argc==3) { physName = argv[2]; }

  // Physics List name defined via environment variable
  //char* path = getenv("PHYSLIST");
  //if (path) { physName = G4String(path); }
	
	physName = "LHEP_EMV";

  // reference PhysicsList via its name
  if(physListFact.IsReferencePhysList(physName)) {
    modulPhysList = physListFact.GetReferencePhysList(physName);
    physListMess = new PhysicsListMessenger();
  } 

  // local Physics List (default)
  if(!modulPhysList) { modulPhysList = new PhysicsList(); }

  // define physics
  runManager->SetUserInitialization(modulPhysList);


	//HistoManager - will be used in EventAction
	G4String output;
	//  File name is provided via 2nd argument  
	if (argc==3)   {
		output = argv[2];
	}
	else output = "output/test.root";
	HistoManager* histo = new HistoManager(output);
	G4String rootname = histo->SetRootName();

  // set mandatory user action class
  //G4VUserPrimaryGeneratorAction* gen_action = new PrimaryGeneratorAction;
  //PrimaryGeneratorAction* gen_action = new PrimaryGeneratorAction;
  PrimaryGeneratorAction* gen_action = new PrimaryGeneratorAction(detector);
  runManager->SetUserAction(gen_action);

	//EventAction* event_action = new EventAction(gen_action);
	//EventAction* event_action = new EventAction(histo);
	EventAction* event_action = new EventAction(histo, gen_action);
  runManager->SetUserAction(event_action );

  // Initialize G4 kernel
  runManager->Initialize();

  // Get the pointer to the UI manager and set verbosities
  //
  G4UImanager* UI = G4UImanager::GetUIpointer();
  UI->ApplyCommand("/run/verbose 0");
  UI->ApplyCommand("/event/verbose 0");
  UI->ApplyCommand("/tracking/verbose 0");
	UI->ApplyCommand("/g4test/CutsAll 1 um");
#ifdef G4VIS_USE
  G4VisManager* visManager = new G4VisExecutive;
  visManager->Initialize();
#endif    
     
  // Get the pointer to the User Interface manager
  //
  G4UImanager * UImanager = G4UImanager::GetUIpointer();  

  if (argc!=1)   // batch mode  
    {
      G4String command = "/control/execute ";
      G4String fileName = argv[1];
      UImanager->ApplyCommand(command+fileName);
    }
  else           // interactive mode : define UI session
    { 
#ifdef G4UI_USE
      G4UIExecutive * ui = new G4UIExecutive(argc,argv);
#ifdef G4VIS_USE
      UImanager->ApplyCommand("/control/execute macro/vis.mac");     
#endif
      ui->SessionStart();
      delete ui;
#endif
     
#ifdef G4VIS_USE
      delete visManager;
#endif     
    }
  // Job termination
  // Free the store: user actions, physics_list and detector_description are
  //                 owned and deleted by the run manager, so they should not
  //                 be deleted in the main() program !
  delete runManager;
	delete histo;

  return 0;
}


